package com.example.music.service

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Intent
import android.media.MediaPlayer
import android.os.Binder
import android.os.Build
import android.os.IBinder
import android.util.Log
import androidx.core.app.NotificationCompat
import com.example.music.MusicDetailActivity
import com.example.music.R
import com.example.music.model.Song

class MusicService : Service() {
    companion object {
        private var instance: MusicService? = null
    }

    private var mediaPlayer: MediaPlayer? = null
    private val binder = MusicBinder()
    private var currentSong: Song? = null
    private val NOTIFICATION_ID = 1
    private val CHANNEL_ID = "MusicServiceChannel"

    inner class MusicBinder : Binder() {
        fun getService(): MusicService = this@MusicService
    }

    override fun onBind(intent: Intent): IBinder {
        return binder
    }

    override fun onCreate() {
        super.onCreate()
        instance = this
        createNotificationChannel()
    }

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                CHANNEL_ID,
                "Music Service Channel",
                NotificationManager.IMPORTANCE_LOW
            ).apply {
                description = "用于音乐播放的通知"
            }
            val manager = getSystemService(NotificationManager::class.java)
            manager.createNotificationChannel(channel)
        }
    }

    fun playSong(song: Song, onPrepared: () -> Unit) {
        try {
            if (currentSong?.id == song.id && mediaPlayer != null) {
                mediaPlayer?.start()
                updateNotification()
                playbackStateChangeListener?.onPlaybackStateChanged(song, true)
                onPrepared()
                return
            }

            currentSong = song
            mediaPlayer?.release()
            mediaPlayer = MediaPlayer().apply {
                setDataSource(song.url)
                setOnPreparedListener {
                    start()
                    startForeground(NOTIFICATION_ID, createNotification())
                    onPrepared()
                    playbackStateChangeListener?.onPlaybackStateChanged(song, true)
                }
                setOnErrorListener { mp, what, extra ->
                    Log.e("MusicService", "播放错误: what=$what, extra=$extra")
                    playbackStateChangeListener?.onPlaybackStateChanged(song, false)
                    false
                }
                setOnCompletionListener {
                    playbackStateChangeListener?.onPlaybackStateChanged(song, false)
                }
                prepareAsync()
            }
        } catch (e: Exception) {
            Log.e("MusicService", "播放失败", e)
            playbackStateChangeListener?.onPlaybackStateChanged(song, false)
        }
    }

    private fun createNotification(): android.app.Notification {
        val intent = Intent(this, MusicDetailActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
        }
        val pendingIntent = PendingIntent.getActivity(
            this, 0, intent,
            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
        )

        return NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle(currentSong?.name ?: "正在播放")
            .setContentText(currentSong?.artist ?: "")
            .setSmallIcon(R.drawable.ic_play)
            .setContentIntent(pendingIntent)
            .setOngoing(true)
            .build()
    }

    fun togglePlayPause() {
        mediaPlayer?.let {
            if (it.isPlaying) {
                pause()
            } else {
                start()
            }
        }
    }

    fun isPlaying(): Boolean = mediaPlayer?.isPlaying == true

    fun seekTo(position: Int) {
        mediaPlayer?.seekTo(position)
    }

    fun getCurrentPosition(): Int = mediaPlayer?.currentPosition ?: 0

    fun getDuration(): Int = mediaPlayer?.duration ?: 0

    fun stop() {
        try {
            mediaPlayer?.stop()
            mediaPlayer?.release()
            mediaPlayer = null
            stopForeground(true)
        } catch (e: Exception) {
            Log.e("MusicService", "停止播放失败", e)
        }
    }

    fun pause() {
        try {
            mediaPlayer?.pause()
            updateNotification()
            playbackStateChangeListener?.onPlaybackStateChanged(currentSong, false)
        } catch (e: Exception) {
            Log.e("MusicService", "暂停失败", e)
        }
    }

    fun start() {
        try {
            if (mediaPlayer == null && currentSong != null) {
                playSong(currentSong!!) {}
            } else {
                mediaPlayer?.start()
                updateNotification()
                playbackStateChangeListener?.onPlaybackStateChanged(currentSong, true)
            }
        } catch (e: Exception) {
            Log.e("MusicService", "开始播放失败", e)
        }
    }

    private fun updateNotification() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForeground(NOTIFICATION_ID, createNotification())
        }
    }

    override fun onDestroy() {
        instance = null
        mediaPlayer?.release()
        mediaPlayer = null
        super.onDestroy()
    }

    fun getCurrentSong(): Song? = currentSong

    fun getPlaybackState(): Triple<Song?, Int, Boolean> {
        return Triple(
            currentSong,
            getCurrentPosition(),
            isPlaying()
        )
    }

    interface OnPlaybackStateChangeListener {
        fun onPlaybackStateChanged(song: Song?, isPlaying: Boolean)
    }

    private var playbackStateChangeListener: OnPlaybackStateChangeListener? = null

    fun setPlaybackStateChangeListener(listener: OnPlaybackStateChangeListener?) {
        playbackStateChangeListener = listener
    }

    fun isPlayingSong(songId: String): Boolean {
        return currentSong?.id == songId && mediaPlayer?.isPlaying == true
    }
} 